package interfaces.menu.options;

import interfaces.menu.AbsMenu;
import interfaces.options.CheckBoxOptionWidget;
import interfaces.options.ComboBoxOptionWidget;
import interfaces.options.OptionWidget;
import interfaces.options.OptionsContainer;
import logic.nodes.nodeSettings.Settings;
import main.InitGame;
import main.ResolutionHandler;

import org.fenggui.event.ISelectionChangedListener;
import org.fenggui.event.SelectionChangedEvent;

import com.jme.scene.state.GLSLShaderObjectsState;

import settings.GraphicSettings;

import fileHandling.ProfileHandler;
import fileHandling.language.Lang;
import fileHandling.language.interfaces.OptionsWindowText;
import fileHandling.language.options.Graphics;
import fileHandling.language.options.OptionValues;

public class GraphicOptionsContent extends OptionContent {
	
	private OptionsContainer simpleOptions, advancedOptions;
	private ComboBoxOptionWidget resolutionComboBox, detailsComboBox;
	private CheckBoxOptionWidget fullscreenWidget;
	private String oldDetails;
	private GraphicSettings oldConfig;
	
	public GraphicOptionsContent(OptionsMenu optionsMenu, AbsMenu menu) {
		super(optionsMenu, menu, "graphics.xml", GraphicSettings.get());
		
		if(!ResolutionHandler.get().init()) return;
		
		simpleOptions = createOptionsContainer(OptionsWindowText.Simple, Graphics.Resolution, Graphics.Fullscreen, Graphics.Details);
		advancedOptions = createOptionsContainer(OptionsWindowText.Advanced, 
				Graphics.Texture_Quality, Graphics.Normal_Quality, Graphics.Bump_Mapping_Quality, Graphics.Specular_Quality, 
				Graphics.Effects_Quality, Graphics.Shader_Quality, Graphics.Texture_Filter, Graphics.Anisotropic_Filter, 
				Graphics.LOD, Graphics.Geometry_Quality, Graphics.Antialiasing);
		
		checkFullscreenSelection(Boolean.valueOf(fullscreenWidget.getValue()).booleanValue());
		
		oldConfig = GraphicSettings.copySettings();
	}
	
	@Override
	protected void addOptionWidget(OptionWidget widget, OptionsContainer container) {
		Lang descr = widget.getDescription();
		if(resolutionComboBox == null && descr == Graphics.Resolution) 
			resolutionComboBox = (ComboBoxOptionWidget)widget;
		else if(detailsComboBox == null && descr == Graphics.Details) {
			detailsComboBox = (ComboBoxOptionWidget)widget;
			oldDetails = detailsComboBox.getValue();
			detailsComboBox.addChangeListener(getDetailsChangeListener());
		} else if(fullscreenWidget == null && descr == Graphics.Fullscreen) {
			fullscreenWidget = (CheckBoxOptionWidget)widget;
			fullscreenWidget.addChangeListener(getFSChangeListener());
		} else if(descr == Graphics.Shader_Quality) {
			if(!GLSLShaderObjectsState.isSupported()) {
				GraphicSettings.get().addOption(Graphics.Shader_Quality, "Low");
				ProfileHandler.changeSettings(GraphicSettings.get());
				return;
			}
		} else if(descr == Graphics.Antialiasing && InitGame.MAX_SAMPLES == 0) return;
		
		super.addOptionWidget(widget, container);
	}
	
	private ISelectionChangedListener getDetailsChangeListener() {
		return new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent selectionChangedEvent) {
				String value = detailsComboBox.getValue();
				if(oldDetails.equals(value)) return;
				oldDetails = value;
				if(value.equals(OptionValues.High.toString())) advancedOptions.setToHigh();
				else if(value.equals(OptionValues.Medium.toString())) advancedOptions.setToMedium();
				else if(value.equals(OptionValues.Low.toString())) advancedOptions.setToLow();
			}
		};
	}
	
	private ISelectionChangedListener getFSChangeListener() {
		return new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent selectionChangedEvent) {
				checkFullscreenSelection(selectionChangedEvent.isSelected());
			}
		};
	}
	
	private void checkFullscreenSelection(boolean isFullscreen) {
		if(isFullscreen) {
			resolutionComboBox.setValues(ResolutionHandler.get().getSortedResolutions(), 
										resolutionComboBox.getValue());
		} else {
			String[] winRes = ResolutionHandler.windowedResolutions;
			String newRes = winRes[0];
			if(containsKey(winRes, resolutionComboBox.getValue())) 
				newRes = resolutionComboBox.getValue();
			resolutionComboBox.setValues(winRes, newRes);
		}
		layout();
	}
	
	private boolean containsKey(String[] values, String key) {
		for(String val : values) {
			if(key.equals(val)) return true;
		}
		return false;
	}

	@Override
	protected void apply() {
		GraphicSettings settings = GraphicSettings.get();
		settings.copySettings(new Settings(simpleOptions), false);
		settings.copySettings(new Settings(advancedOptions), false);
		ProfileHandler.changeSettings(GraphicSettings.get());
		InitGame.get().changeGraphicSettings(oldConfig);
		oldConfig = GraphicSettings.copySettings();
	}
}